import { ref } from 'vue'

export default (state: any) => {
    const formRef = ref()

    // 内置规则
    const commonRule: any = {
        required: { required: true, message: '不能为空' },
    }
    
    // 自定义最大长度规则
    const createMaxRule = (str: string) => {
        const num = Number(str.replace('max', ''))
        return { max: num, message: `最大长度 ${num}` }
    }
    
    const validator: any = {
        // 校验值是否存在
        async exist(rule: any, value: any, callback: any, ruleConfig: any) {
            let { data } = await ruleConfig.api(`${rule.field}='${value}'`);
            const key = ruleConfig.checkKey || 'id' // 自定义比较字段
            if (data && data.length > 0 && data[0][key] !== state.form[key]) {
                callback(new Error('数据已存在'));
            }
        }
    }
    
    const formatRules = (rules: any[]) => {
        let _rules: any[] = []
        if (rules && Array.isArray(rules)) {
            rules.forEach((ruleConfig: any) => {
                const obj = typeof ruleConfig === 'string'
                    ? ruleConfig.includes('max')
                        ? createMaxRule(ruleConfig)
                        : commonRule[ruleConfig]
                    : ruleConfig && (ruleConfig.name || ruleConfig.validator)
                        ? {
                            validator: async(rule: any, value: any, callback: any) => {
                                if (value) {
                                    if (ruleConfig.validator) {
                                        return ruleConfig.validator(rule, value, callback, state.form, formRef)
                                    } else {
                                        return validator[ruleConfig.name](rule, value, callback, ruleConfig)
                                    }
                                } else {
                                    callback();
                                }
                            },
                            trigger: ruleConfig.trigger
                        }
                        : ruleConfig
                _rules.push(obj)
            })
        } 
        return _rules
    }

    return {
        formatRules,
        formRef
    }
}